package com.apartment.own.service.impl;

import com.apartment.common.utils.ChineseToFirstLetterUtil;
import com.apartment.common.utils.CollectionHelper;
import com.apartment.common.utils.DateUtils;
import com.apartment.common.utils.StringSplit;
import com.apartment.own.domain.*;
import com.apartment.own.domain.constant.ClassNameConstants;
import com.apartment.own.domain.constant.RoomCode;
import com.apartment.own.domain.enums.LeaseModeEnum;
import com.apartment.own.domain.enums.ResourceQueryConditionEnum;
import com.apartment.own.mapper.CommonMapper;
import com.apartment.own.mapper.OwnResHouseResourceMapper;
import com.apartment.own.request.house.HouseInsertRequest;
import com.apartment.own.request.house.HouseQuery;
import com.apartment.own.response.res.CommonGroupResponse;
import com.apartment.own.response.common.ExitCityResp;
import com.apartment.own.response.res.HouseSelectResponse;
import com.apartment.own.response.res.PlotResp;
import com.apartment.own.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.rmi.dgc.Lease;
import java.util.*;

/**
 * 房源Service业务层处理
 *
 * @author @Dog_E
 * @date 2020-08-28
 */
@Service
public class OwnResHouseResourceServiceImpl extends ServiceImpl<OwnResHouseResourceMapper, OwnResHouseResource> implements IOwnResHouseResourceService {


    @Autowired
    private OwnResHouseResourceMapper ownResHouseResourceMapper;
    @Autowired
    private IOwnResHouseContractService ownResHouseContractService;
    @Autowired
    private IOwnOrdExtraChargeService iOwnOrdExtraChargeService;
    @Autowired
    private IOwnOrdCashPledgeService iOwnOrdCashPledgeService;
    @Autowired
    private IOwnResPropertyFeeService iOwnResPropertyFeeService;
    @Autowired
    private IOwnResArticleService iOwnResArticleService;
    @Autowired
    private IOwnResArticleInventoryService iOwnResArticleInventoryService;
    @Autowired
    private IOwnResHouseRoomConfService iOwnResHouseRoomConfService;
    @Autowired
    private CommonMapper commonMapper;
    @Autowired
    private IOwnAccountDetailsService iOwnAccountDetailsService;


    /**
     * 查询房源
     *
     * @param id 房源ID
     * @return 房源
     */
    @Override
    public OwnResHouseResource selectOwnResHouseResourceById(Long id) {
        return ownResHouseResourceMapper.selectOwnResHouseResourceById(id);
    }

    /**
     * 查询房源列表
     *
     * @param ownResHouseResource 房源
     * @return 房源
     */
    @Override
    public List<OwnResHouseResource> selectOwnResHouseResourceList(OwnResHouseResource ownResHouseResource) {
        return ownResHouseResourceMapper.selectOwnResHouseResourceList(ownResHouseResource);
    }

    /**
     * 新增房源
     *
     * @param ownResHouseResource 房源
     * @return 结果
     */
    @Override
    public int insertOwnResHouseResource(OwnResHouseResource ownResHouseResource) {
        ownResHouseResource.setCreateTime(DateUtils.getNowDate());
        return ownResHouseResourceMapper.insertOwnResHouseResource(ownResHouseResource);
    }

    /**
     * 修改房源
     *
     * @param ownResHouseResource 房源
     * @return 结果
     */
    @Override
    public int updateOwnResHouseResource(OwnResHouseResource ownResHouseResource) {
        ownResHouseResource.setUpdateTime(DateUtils.getNowDate());
        return ownResHouseResourceMapper.updateOwnResHouseResource(ownResHouseResource);
    }

    /**
     * 批量删除房源
     *
     * @param ids 需要删除的房源ID
     * @return 结果
     */
    @Override
    public int deleteOwnResHouseResourceByIds(Long[] ids) {
        return ownResHouseResourceMapper.deleteOwnResHouseResourceByIds(ids);
    }

    /**
     * 删除房源信息
     *
     * @param id 房源ID
     * @return 结果
     */
    @Override
    public int deleteOwnResHouseResourceById(Long id) {
        return ownResHouseResourceMapper.deleteOwnResHouseResourceById(id);
    }

    @Autowired
    RedisTemplate redisTemplate;
    /**
     * des. 修改房源信息
     *
     * @author : RazaJin
     * @date : 2020/9/1 0001 上午 10:32
     */
    @Override
    public int editBaseHouseInformation(HouseInsertRequest request) {
        /* 房屋对象 */
        OwnResHouseResource entity = new OwnResHouseResource();
        BeanUtils.copyProperties(request, entity);

        entity.setConfiguration(StringSplit.append(request.getConfigurationList()));
        entity.setImages(StringSplit.append(request.getImagesList()));
        entity.setFeature(StringSplit.append(request.getFeatureList()));

        //业务逻辑 根据是否有主键id 判断是添加还是修改
        Boolean result = save(entity);
        request.setId(entity.getId());

        /* 和房间一对多 */
        List<OwnResHouseRoomConf> ownResHouseRoomConfList = editHouseRoom(request);

        /* 和房源一对多 */
        OwnResHouseContract ownResHouseContract = editHouseContract(request);
        ownResHouseContractService.save(ownResHouseContract);

        /* 额外消费 */
        request.getOwnResHouseContract().getOwnOrdExtraChargeList().forEach(ele -> {
            ele.setForeignId(ownResHouseContract.getId());
            ele.setSurfaceName(ClassNameConstants.ORD_EXTRA_CHARGE_FK_RES_HOUSE_CONTRACT);
        });
        List<OwnOrdExtraCharge> ownOrdExtraChargeList = request.getOwnResHouseContract().getOwnOrdExtraChargeList();
        /* 押金 */
        request.getOwnResHouseContract().getOwnOrdCashPledgeList().forEach(ele -> {
            //TODO:这个魔法值改为常量或者枚举
            ele.setSurfaceName(ClassNameConstants.ORD_CASH_PLEDGE_FK_RES_HOUSE_CONTRACT);
            ele.setForeignId(ownResHouseContract.getId());
        });

        List<OwnOrdCashPledge> ownOrdCashPledgeList = request.getOwnResHouseContract().getOwnOrdCashPledgeList();
        /* 生活费用 */
        request.getOwnResPropertyFeeList().forEach(ele -> {
            ele.setForeignId(ownResHouseContract.getId());
            ele.setSurfaceName(ClassNameConstants.RES_HOUSE_CONTRACT_FK_OWN_RES_PROPERTY_FEE);
        });
        List<OwnResPropertyFee> ownResPropertyFeeList = request.getOwnResPropertyFeeList();
        /* 房间物品 */
        request.getOwnResArticleInventories().forEach(ele -> {
            ele.setForeignId(request.getId());
            ele.setSurfaceName(ClassNameConstants.RES_ARTICLE_INVENTORY_FK_OWN_RES_HOUSE_RESOURCE);
        });
        //TODO:这个是房间物品 还没做
        List<OwnResArticleInventory> ownResArticleInventories = request.getOwnResArticleInventories();

        //处理完数据后保存到数据库
        iOwnOrdExtraChargeService.saveBatch(ownOrdExtraChargeList);
        iOwnOrdCashPledgeService.saveBatch(ownOrdCashPledgeList);
        iOwnResPropertyFeeService.saveBatch(ownResPropertyFeeList);
        iOwnResArticleInventoryService.saveBatch(ownResArticleInventories);
        iOwnResHouseRoomConfService.saveBatch(ownResHouseRoomConfList);
        //调用生成账单
        iOwnAccountDetailsService.createPaymentList(request.getOwnResHouseContract());

        return 1;
    }

    @Override
    public List<CommonGroupResponse> listHouse(HouseQuery request) {

        //选中的是否是无限
        boolean isUnlimited = (request.getChecked().equals(ResourceQueryConditionEnum.UNLIMITED.getId()));
        //判断是否是整租
        boolean leaseMode = LeaseModeEnum.ENTIRE.getId().equals(request.getLeaseMode());
        List<HouseSelectResponse> list = commonMapper.listHouseAndRoom(new QueryWrapper<OwnResHouseResource>()
                .eq("resource.lease_model", leaseMode ? LeaseModeEnum.ENTIRE.getId() : LeaseModeEnum.PARTED.getId())
                .and(i -> i
                        .or().like((isUnlimited || ResourceQueryConditionEnum.TENANT_NAME.getId().equals(request.getChecked())), "room.tenant_name", request.getKeyWord())
                        .or().like((isUnlimited || ResourceQueryConditionEnum.TENANT_PHONE.getId().equals(request.getChecked())), "room.tenant_phone", request.getKeyWord())
                        .or().like((isUnlimited || ResourceQueryConditionEnum.SOURCE_ID.getId().equals(request.getChecked())), "resource.id", request.getKeyWord())
                        .or().like((isUnlimited || ResourceQueryConditionEnum.NO.getId().equals(request.getChecked())), "resource.no", request.getKeyWord())
                        .or().like((isUnlimited || ResourceQueryConditionEnum.SOURCE_NUMBER.getId().equals(request.getChecked())), "resource.id", request.getKeyWord())
                )
                .groupBy((leaseMode), "resource.id")
        );
        Map<String, List<HouseSelectResponse>> getHousingEstate = new CollectionHelper<HouseSelectResponse>().groupObjectBy(list, leaseMode ? "getHousingEstate" : "getId");

        List<CommonGroupResponse> commonGroupResponses = new ArrayList<>();
        getHousingEstate.forEach((k, v) -> {
            if (leaseMode) {
                commonGroupResponses.add(new CommonGroupResponse(k, v));
            } else {
                HouseSelectResponse ele = v.get(0);
                String key = splice(null, ele.getHousingEstate(), ele.getNo(), ele.getUnit(), ele.getHouseNo(), null);
                commonGroupResponses.add(new CommonGroupResponse(key, v));
            }
        });
        return commonGroupResponses;

    }

    @Override
    public HouseInsertRequest houseInfo(String id) {
        OwnResHouseResource ownResHouseResource = ownResHouseResourceMapper.selectById(id);
        HouseInsertRequest houseInsertRequest = new HouseInsertRequest();
        if(ownResHouseResource == null){return houseInsertRequest;}
        BeanUtils.copyProperties(ownResHouseResource,houseInsertRequest);
        houseInsertRequest.setConfigurationList(StringSplit.split(houseInsertRequest.getConfiguration()));
        houseInsertRequest.setFeatureList(StringSplit.split(houseInsertRequest.getFeature()));
        houseInsertRequest.setImagesList(StringSplit.split(houseInsertRequest.getImages()));
        return houseInsertRequest;
    }

    /**
     *  查询房源表中的城市
     *
     * @return 分组列表
     */
    @Override
    public List<CommonGroupResponse>  listExistCity() {
        List<ExitCityResp> list = ownResHouseResourceMapper.selectExistCity();
        ArrayList<CommonGroupResponse> responses = new ArrayList<>();
        list.forEach(x->{
            if (null != x.getCityValue()&&null != x.getCityId()){
                String firstLetter = ChineseToFirstLetterUtil.ChineseToFirstLetter(x.getCityValue());
                String substring = firstLetter.substring(0, 1);
                x.setFirstLetter(substring);
            }
        });
                Map<String, List<ExitCityResp>> firstLetter = new CollectionHelper<ExitCityResp>().groupObjectBy(list,"getFirstLetter");
        firstLetter.forEach((k,v)->{
            responses.add(new CommonGroupResponse(k,v));
        });
        return responses;
    }

    /**
     * 查询已有小区
     * @return
     */
    @Override
    public List<CommonGroupResponse> listExistPlot(String[] cityId) {

            List<String> list = ownResHouseResourceMapper.listExistPlot(new QueryWrapper<>().in((cityId!=null&&cityId.length!=0),"city_id",cityId));
            ArrayList<CommonGroupResponse> responses = new ArrayList<>();
            ArrayList<PlotResp> plotResps = new ArrayList<>();
            final PlotResp[] plotResp = {null};
            list.forEach(x->{
                String firstLetter = ChineseToFirstLetterUtil.ChineseToFirstLetter(x);
                String substring = firstLetter.substring(0, 1);
                plotResp[0] = new PlotResp(x,substring);
                plotResps.add(plotResp[0]);
        });
            Map<String, List<PlotResp>> getFirstLetter = new CollectionHelper<PlotResp>().groupObjectBy(plotResps, "getFirstLetter");
            getFirstLetter.forEach((k,v)->{
                responses.add(new CommonGroupResponse(k,v));
        });
            return responses;
       
    }

    @Override
    public List<Map> listHouseByHouseName(HouseQuery request) {
        LeaseModeEnum leaseModeEnum = LeaseModeEnum.getEnum(request.getLeaseMode());
        List<HouseSelectResponse> list;
        if (leaseModeEnum == null) {return null;}
        Integer count = 10;
        switch (leaseModeEnum){
            case ENTIRE:
                list = selectHouseByKey(request.getKeyWord(),true,count);
                break;
            case PARTED:
                list = selectHouseByKey(request.getKeyWord(),false,count);
                break;
            case ALL:
                list = new ArrayList<>(selectHouseByKey(request.getKeyWord(), true,count));
                list.addAll(selectHouseByKey(request.getKeyWord(),false,count - list.size()));
                break;
            default:
                return null;
        }

        List<Map> maps = new ArrayList<>();

        list.forEach(ele -> {
            Map<Object, Object> objectObjectMap = new HashMap<>();
            objectObjectMap.put("resourceId",ele.getId());
            objectObjectMap.put("roomId",ele.getRoomId());
            objectObjectMap.put("name",ele.getRoomName());
            objectObjectMap.put("housingEstate",ele.getHousingEstate());
            maps.add(objectObjectMap);
        });


        return maps;
    }

    /**
     * des.
     * keyword 搜索词
     * leaseMode  true 是整租  false 是合租
     * @author       : RazaJin
     * @date         : 2020/9/12 0012 下午 5:02
     */
    public List<HouseSelectResponse> selectHouseByKey(String keyword ,boolean leaseMode ,Integer limit){
        StringBuilder limit_ = new StringBuilder("limit ").append(limit);
        return commonMapper.listHouseAndRoom(new QueryWrapper<OwnResHouseResource>()
                .eq("resource.lease_model", leaseMode?LeaseModeEnum.ENTIRE.getId():LeaseModeEnum.PARTED.getId())
                .and(i -> i
                        .or().like(!leaseMode
                                , "room.room_no",keyword)
                        .or().like(!leaseMode
                                , "room.room_name", keyword)
                        .or().like("resource.id", keyword)
                        .or().like( "resource.no", keyword)
                        .or().like("resource.id", keyword)
                        .or().like("resource.housing_estate",keyword)
                )
                .groupBy((leaseMode),"resource.id")

                .last(limit_.toString())
        );
    }


    /**
     * des. 编辑房间
     *
     * @author : RazaJin
     * @date : 2020/9/1 0001 上午 10:35
     */
    public List<OwnResHouseRoomConf> editHouseRoom(HouseInsertRequest request) {
        //TODO:这里 现在的逻辑是 新增的时候吧 前端传的一个房间配置兑现处理成一个房间配置信息集合 这个直接初始化了数组了 修改用的时候需要改动
        //获取一共有几个房间  0 :表示无房间
        int roomCount = request.getEndBedRoom() != null
                ? request.getEndBedRoom()
                : (request.getBeforeBedRoom() != null
                    ? request.getBeforeBedRoom()
                    : 0);
        //房间配置信息 由list转String
        request.getHouseRoomConfRequest().setConfiguration(StringSplit.append(request.getConfigurationList()));
        request.getHouseRoomConfRequest().setImages(StringSplit.append(request.getImagesList()));
        request.getHouseRoomConfRequest().setFeature(StringSplit.append(request.getFeatureList()));
        for (int i = 0; i < roomCount; i++) {
            //TODO:如果房间是第一次添加的  设置房间号
            OwnResHouseRoomConf newRoom = new OwnResHouseRoomConf();
            //复制属性
            BeanUtils.copyProperties(request.getHouseRoomConfRequest(), newRoom);
            //关联房源表
            newRoom.setKeyResourceId(request.getId());
            //设置房间号
            newRoom.setRoomNo(RoomCode.code[i]);
            //设置整租还是合租
            newRoom.setLeaseModel(request.getLeaseModel());
            //拼接房间名称
            String name = splice(request.getCityValue()
                    , request.getHousingEstate()
                    , request.getNo()
                    , request.getUnit()
                    , request.getHouseNo()
                    //这判断如果是整租的话 不添加 roomNo
                    , (request.getLeaseModel().equals(LeaseModeEnum.PARTED.getId())) ? newRoom.getRoomNo() : null);
            newRoom.setRoomName(name);
            if(request.getOwnResHouseRoomConfList() == null){ request.setOwnResHouseRoomConfList(new ArrayList<>()); }
            request.getOwnResHouseRoomConfList().add(newRoom);
            //判断如果是整租,直接跳出循环
            if(LeaseModeEnum.ENTIRE.getId().equals(request.getLeaseModel())){
                break;
            }
        }
        //根据房间数生成房间
        //循环
        //判断是整租还是合租
        //赋值
        return request.getOwnResHouseRoomConfList();
    }

    /**
     * des. 编辑合同信息
     * @author       : RazaJin
     * @date         : 2020/9/2 0002 下午 5:53
     */
    public OwnResHouseContract editHouseContract(HouseInsertRequest request){
        //处理合同图片
        request.getOwnResHouseContract().setConstraintImages(StringSplit.append(request.getConstraintImages()));
        request.getOwnResHouseContract().setCertificate(StringSplit.append(request.getCertificate()));
        request.getOwnResHouseContract().setKeyHouseResourceId(request.getId());
        return request.getOwnResHouseContract();
    }

    /**
     * des. 根据小区和位置信息拼接房间 或者小区名称
     *
     * @author : RazaJin
     * 市+小区+楼号+单元+房间号+房间code
     * @date : 2020/9/2 0002 上午 10:12
     */
    public String splice(String cityValue, String housingEstate, Integer no, Integer unit, Integer houseNo, String houseCode) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(StringUtil.isNotEmpty(cityValue) ? (cityValue) : "");
        stringBuilder.append(StringUtil.isNotEmpty(housingEstate) ? ("-" + housingEstate) : "");
        stringBuilder.append(null != no ? ("-" + no + "号楼") : "");
        stringBuilder.append(null != unit ? ("-" + unit + "单元") : "");
        stringBuilder.append(null != houseNo ? ("-" + houseNo + "号") : "");
        stringBuilder.append(StringUtil.isNotEmpty(houseCode) ? ("-" + houseCode) : "");
        return stringBuilder.toString();
    }
}
